/**
 * The database package of the application.
 */
package fr.umlv.m2.android.quizz.database;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;

/**
 * This class defines the database user object.
 * It allows to select, insert, update and delete user object. 
 *  
 * @author Gambouele Bertrand.
 * @author Viravout Alexandre.
 */
public class UserDb {
	/**
	 * The database version.
	 */
	private static final int DB_VERSION = 1;
	/**
	 * The database name.
	 */
	private static final String DB_NAME = "quizz.db";

	/**
	 * The user table name.
	 */
	private static final String USER_TABLE = "user";
	/**
	 * The user id column name.
	 */
	private static final String ID = "id";
	/**
	 * The user id column number.
	 */
	private static final int ID_COL_NUM = 0;
	/**
	 * The user name column name.
	 */
	private static final String NAME = "name";
	/**
	 * The user name column number.
	 */
	private static final int NAME_COL_NUM = 1;

	/**
	 * The database of the application.
	 */
	private SQLiteDatabase db;
	/**
	 * The database open helper.
	 */
	private final QuizzDatabaseOpenHelper quizzSQLite;

	/**
	 * Create the database user object.
	 * 
	 * @param context the context.
	 */
	public UserDb(Context context) {
		this.quizzSQLite = new QuizzDatabaseOpenHelper(context, DB_NAME, null, DB_VERSION);
	}

	/**
	 * Opens the database.
	 */
	public void open() {
		this.db = this.quizzSQLite.getWritableDatabase();
	}

	/**
	 * Closes the database.
	 */
	public void close() {
		this.db.close();
	}

	/**
	 * Gets the database.
	 * 
	 * @return the database.
	 */
	public SQLiteDatabase getDb() {
		return this.db;
	}
	
	/**
	 * Gets the number of user.
	 * 
	 * @return the number of user.
	 */
	public long getNbUser() {
		return DatabaseUtils.queryNumEntries(this.db, USER_TABLE);
	}

	/**
	 * Inserts an user in the database.
	 * 
	 * @param user the user to insert.
	 * @return the row ID of the newly inserted row, or -1 if an error occurred.
	 */
	public long insertUser(User user) {
		ContentValues values = new ContentValues();

		values.put(NAME, user.getName());

		return this.db.insert(USER_TABLE, null, values);
	}
 
	/**
	 * Updates user data according his id.
	 * 
	 * @param id the user id.
	 * @param user the new user object.
	 * @return the number of rows affected.
	 */
	public int updateUser(long id, User user) {
		ContentValues values = new ContentValues();
		
		values.put(NAME, user.getName());
		
		return this.db.update(USER_TABLE, values, ID + " = " + id, null);
	}
 
	/**
	 * Removes user according his id.
	 * 
	 * @param id the user id.
	 * @return the number of rows affected
	 * if a whereClause is passed in, 0 otherwise.
	 * To remove all rows and get a count pass "1" as the whereClause.
	 */
	public int removeUserWithID(long id){
		return this.db.delete(USER_TABLE, ID + " = " + id, null);
	}

	private User cursorToUser(Cursor cursor) {
		if(cursor.getCount() == 0) {
			return null;
		} else {
			cursor.moveToFirst();
		}
		
		User user = new User();
		user.setId(cursor.getInt(ID_COL_NUM));
		user.setName(cursor.getString(NAME_COL_NUM));
		cursor.close();
 
		return user;
	}
	
	/**
	 * Gets user object according his id.
	 * 
	 * @param id the user id.
	 * @return the user object, null if no row.
	 */
	public User getUserWithId(long id) {
		Cursor cursor = this.db.query(
				USER_TABLE,
				new String[] { ID, NAME },
				ID + " = " + id,
				null, null, null, null
		);

		return this.cursorToUser(cursor);
	}
	
	/**
	 * Gets user object according his name.
	 * 
	 * @param name the user name.
	 * @return the user object, null if not row.
	 */
	public User getUserWithName(String name) {
		Cursor cursor = this.db.query(
				USER_TABLE,
				new String[] { ID, NAME },
				NAME + " LIKE \"" + name + "\"",
				null, null, null, null
		);
		
		return this.cursorToUser(cursor);
	}
	
	private List<User> cursorToUsers(Cursor cursor) {		
		if(cursor.getCount() == 0) {
			return null;
		} else {
			cursor.moveToFirst();
		}
		
		User user;
		List<User> users = new ArrayList<User>();		
		do {
			user = new User();
			user.setId(cursor.getInt(ID_COL_NUM));
			user.setName(cursor.getString(NAME_COL_NUM));
			users.add(user);
		} while (cursor.moveToNext());
		cursor.close();

		return users;
	}
	
	/**
	 * Gets all users of the database.
	 * 
	 * @return the list of user.
	 */
	public List<User> getAllUsers() {
		Cursor cursor = this.db.query(
				USER_TABLE,
				new String[] { ID, NAME },
				null, null, null, null, null
		);
		
		return this.cursorToUsers(cursor);
	}
}
